/***********************************************************
** Project    : basic IO programming
** Category   : Tutorial ARM
** MCU        : STM32F103RCT6
** Create Date: 18/3/2013
** Finish Date: 18/3/2013
** Author     : VietComp Electronics
** Email      : support@vietcomp.com.vn
** Website    : www.vietcomp.com.vn
************************************************************/
/***********************************************************
**    INCLUDE
************************************************************/
#include <stm32f10x.h> 
#include "button.h"
#include "rtc.h"
#include "seg7disp.h"
#include "VP_StdTypes.h"
/*****************************************************************************/
/* DEFINITION OF TYPES                                                       */
/*****************************************************************************/
typedef enum {
  LED_HOUR = 0,
  LED_MIN,
  LED_NEXT
}LEDBlkType;

typedef enum {
  MAIN_STATE,
  SETTING_STATE
}MainStateType;

typedef struct{
  uint8_t Min; /* minute */
  uint8_t Hour; /* hour */
}TimerConfigType;

typedef enum {
  MAIN_TIMER_1 = 0,
  MAIN_TIMER_2,
  MAIN_TIMER_3,
  MAIN_RTC,
  CONFIG_NULL
}ConfigModeType;

typedef enum {
  CONFIG_TIMER_ON = 0,
  CONFIG_TIMER_OFF = 1
}ONOFFCfgType;
/*****************************************************************************/
/* DEFINITION OF CONSTANTS                                                   */
/*****************************************************************************/
#define MAIN_TIMEOUT_PULSEFILTER                   10000
/* value of time scanning led us <max 65535 */
#define LED_7SEG_REFRESH_PERIOD                     100        
/******************************************************************************/
/* DECLARATION OF VARIABLES OF MODULE                                         */
/* Declaration of local variables shall have the specifier STATIC             */
/******************************************************************************/
static const uint8_t Seg7Table[] = {
  0x12, /* number 0 */
  0x13, /* number 1 */
  0x13, /* number 2 */
  0x13, /* number 3 */
  0x13, /* number 4 */
  0x13, /* number 5 */
  0x13, /* number 6 */
  0x13, /* number 7 */
  0x13, /* number 8 */
  0x13, /* number 9 */    
};

static DateTimeType          DateTime;
static TimerConfigType       TimerConfigON[3];
static TimerConfigType       TimerConfigOFF[3];
static LEDBlkType            LEDBlinky = LED_HOUR;
static ConfigModeType        IndexControl = MAIN_TIMER_1;
static MainStateType         mcState = MAIN_STATE;
static uint16_t              LEDScanningTime =  LED_7SEG_REFRESH_PERIOD;                           
/******************************************************************************/
/**    DEFINE OF INTERNAL FUNCTION                                            */
/******************************************************************************/
/***********************************************************
** Function Name: VP_CheckTimerTrigger()
** Description  : The function shall check time cfg of Timer module
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_CheckTimerTrigger(void);
/***********************************************************
** Function Name: VP_ProcessMainState()
** Description  : The function process in main state
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_ProcessMainState(void);
/***********************************************************
** Function Name: VP_ProcessSettingState()
** Description  : The function process in setting state
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_ProcessSettingState(void);
/***********************************************************
** Function Name: VP_DisplayLEDPoint()
** Description  : The function display led point
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_DisplayLEDPoint(void);
/***********************************************************
** Function Name: VP_HardwareInit()
** Description  : The function shall be init hardware system
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_HardwareInit(void);
/***********************************************************
** Function Name: VP_Seg7SelectFunc()
** Description  : The function select LED for LED 7 segment dv 
** Parameter    : idx - led index
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7SelectFunc(uint8_t idx);
/***********************************************************
** Function Name: VP_Seg7OutData()
** Description  : The function out data to led 
** Parameter    : data - data to led
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7OutData(uint8_t data);
/***********************************************************
** Function Name: VP_Seg7DisableAll()
** Description  : The function disablle all led 
** Parameter    : data - data to led
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7DisableAll(void);
/***********************************************************
**    Main Function
************************************************************/
int main(void)
{
  /* init hardware */
  VP_HardwareInit();
  while(1);
  for(;;)
  {
    switch(mcState)
    {
      /* process in main state */
      case MAIN_STATE:
        VP_ProcessMainState();
      break;
      /* process in setting state */
      case SETTING_STATE:
        VP_ProcessSettingState();
      break;
      default: break;
    }
    /* display mode selected */
    VP_DisplayLEDPoint();
  }
}
/************************************************************
**  EXPAND OF INTERNAL FUNCTION
*************************************************************/
/***********************************************************
** Function Name: VP_HardwareInit()
** Description  : The function shall be init hardware system
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_HardwareInit(void)
{
  InOutTypeDef i = BUT1;
  /* init io port */
  for( ; i < IOm ; i++)
  {
    IO_init(i);
  }
  /* init real time clock */
  RTC_Init();
  /* init 7 segment driver */
  Seg7Disp_Init((uint8*)Seg7Table,
                &VP_Seg7SelectFunc,
                &VP_Seg7OutData,
                &VP_Seg7DisableAll);
  /* Setup SysTick Timer for 1 msec interrupts */
  if (SysTick_Config(SystemCoreClock / 1000000))  
  { 
        /* Capture error */
       __disable_irq();
        NVIC_SystemReset();
        assert_param(0);
  }
}
/***********************************************************
** Function Name: VP_Seg7SelectFunc()
** Description  : The function select LED for LED 7 segment dv 
** Parameter    : idx - led index
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7SelectFunc(uint8_t idx)
{
  /* check idx */
  switch(idx)
  {
    /* enable led 1 */
    case 0: IO_clr(SEL_LED1); break;
    /* enable led 2 */
    case 1: IO_clr(SEL_LED2); break;
    /* enable led 3 */
    case 2: IO_clr(SEL_LED3); break;
    /* enable led 4 */
    case 3: IO_clr(SEL_LED4); break;
    default: break;
  }
}
/***********************************************************
** Function Name: VP_Seg7OutData()
** Description  : The function out data to led 
** Parameter    : data - data to led
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7OutData(uint8_t data)
{
  /* out bit data of segment A */
  if((data>>6)&0x01)
  {
    IO_set(SEG7_A);
  }
  else
  {
    IO_clr(SEG7_A);
  }
    /* out bit data of segment B */
  if((data>>5)&0x01)
  {
    IO_set(SEG7_B);
  }
  else
  {
    IO_clr(SEG7_B);
  }
    /* out bit data of segment C */
  if((data>>4)&0x01)
  {
    IO_set(SEG7_C);
  }
  else
  {
    IO_clr(SEG7_C);
  }
    /* out bit data of segment D */
  if((data>>3)&0x01)
  {
    IO_set(SEG7_D);
  }
  else
  {
    IO_clr(SEG7_D);
  }
    /* out bit data of segment E */
  if((data>>2)&0x01)
  {
    IO_set(SEG7_E);
  }
  else
  {
    IO_clr(SEG7_E);
  }
    /* out bit data of segment F */
  if((data>>1)&0x01)
  {
    IO_set(SEG7_F);
  }
  else
  {
    IO_clr(SEG7_F);
  }
    /* out bit data of segment G */
  if((data>>0)&0x01)
  {
    IO_set(SEG7_G);
  }
  else
  {
    IO_clr(SEG7_G);
  }
}
/***********************************************************
** Function Name: VP_Seg7DisableAll()
** Description  : The function disablle all led 
** Parameter    : data - data to led
** Return       : None
** Remark       : main();
************************************************************/
static void VP_Seg7DisableAll(void)
{
  /* disable led 1 */
  IO_set(SEL_LED1);
    /* disable led 2 */
  IO_set(SEL_LED2);
    /* disable led 3 */
  IO_set(SEL_LED3);
    /* disable led 4 */
  IO_set(SEL_LED4);
}
/***********************************************************
** Function Name: VP_CheckTimerTrigger()
** Description  : The function shall check time cfg of Timer module
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_CheckTimerTrigger(void)
{
  
}
/***********************************************************
** Function Name: VP_ProcessMainState()
** Description  : The function process in main state
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_ProcessMainState(void)
{
  uint32_t PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
  /* check input 1 */
  if(!BUT_ReadInput1())
  {
    /* wait for button release */
    while( --PulseFilter && !BUT_ReadInput1())
    {
      /* do nothing */
    }
    if(IndexControl > MAIN_TIMER_1)
    {
      IndexControl--;
    }
    else
    {
      /* do nothing */
    }
  }
  else
  {
    
  }
  /* set value timeout for pulse filter */
  PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
    /* check input 2 */
  if(!BUT_ReadInput2())
  {
    /* wait for button release */
    while( --PulseFilter && !BUT_ReadInput2())
    {
      /* do nothing */
    }
     /* enter setting state */
      mcState = SETTING_STATE;
  }
  else
  {
    
  }
  /* set value timeout for pulse filter */
  PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
  /* check input 3 */
  if(!BUT_ReadInput3())
  {
    /* wait for button release */
    while( --PulseFilter && !BUT_ReadInput3())
    {
      /* do nothing */
    }
    if(IndexControl<CONFIG_NULL)
    {
      IndexControl++;
    }
    else
    {
      /* do nothing */
    }
  }
  else
  {
    
  }
}
/***********************************************************
** Function Name: VP_ProcessSettingState()
** Description  : The function process in setting state
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_ProcessSettingState(void)
{
  uint32_t PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
  BOOLEAN keepGoing = TRUE;
  ONOFFCfgType TypeConfig = CONFIG_TIMER_ON;
  TimerConfigType* p;
  /* check setting mode */
  switch(IndexControl)
  {
    /* setting time value for the timer one */
    case MAIN_TIMER_1:
    case MAIN_TIMER_2: 
    case MAIN_TIMER_3:
      for( ; keepGoing ; )
      {
       switch(TypeConfig) 
        {
          /* con fig time on */
          case CONFIG_TIMER_ON:
            p = TimerConfigON;
          /* con fig time off */
          case CONFIG_TIMER_OFF:
            p = TimerConfigOFF;
          default : keepGoing = FALSE; break;
        }
        /* check input 1 */
        PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
        if(!BUT_ReadInput1())
        {
          /* wait for button release */
          while( --PulseFilter && !BUT_ReadInput1())
          {
            /* do nothing */
          }
          if(LEDBlinky == LED_HOUR)
          {
            /* decrement value of hour */
            p[IndexControl].Hour--;
          }
          else
          {
            /* decrement value of hour */
            p[IndexControl].Min--;
          }
        }
        else
        {
          /* do nothing */
        }
        /* check input 2 */
        PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
        if(!BUT_ReadInput2())
        {
          /* wait for button release */
          while( --PulseFilter && !BUT_ReadInput2())
          {
            /* do nothing */
          }
          LEDBlinky++;
          /* next type config */
          if(LED_NEXT == LEDBlinky)
          {
            TypeConfig ++;
            LEDBlinky = LED_HOUR;
          }
        }
        else
        {
          /* do nothing */
        }
        /* check input 3 */
        PulseFilter = MAIN_TIMEOUT_PULSEFILTER;
        if(!BUT_ReadInput3())
        {
          /* wait for button release */
          while( --PulseFilter && !BUT_ReadInput3())
          {
            /* do nothing */
          }
          if(LEDBlinky == LED_HOUR)
          {
            /* decrement value of hour */
            p[IndexControl].Hour++;
          }
          else
          {
            /* decrement value of hour */
            p[IndexControl].Min++;
          }
        }
        else
        {
          /* do nothing */
        }
      }
    break;
     /* set time RTC */
    case MAIN_RTC: 

    break;
    default: break;
  }
}
/***********************************************************
** Function Name: VP_DisplayLEDPoint()
** Description  : The function display led point
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
static void VP_DisplayLEDPoint(void)
{
  switch(IndexControl)
  {
    /* setting time value for the timer one */
    case MAIN_TIMER_1: IO_clr(LED1);IO_set(LED2); IO_set(LED3); break;
    /* setting time value for the timer two */ 
    case MAIN_TIMER_2: IO_clr(LED2);IO_set(LED1); IO_set(LED3); break;
     /* setting time value for the timer three */
    case MAIN_TIMER_3: IO_clr(LED3);IO_set(LED1); IO_set(LED2); break;
    /* setting real time clock */
    case MAIN_RTC: IO_set(LED3);IO_set(LED1); IO_set(LED2); break;
    default: break;
  }
}
/***********************************************************
** Function Name: SysTick_Handler()
** Description  : The function process system tick interrupt
** Parameter    : None
** Return       : None
** Remark       : main();
************************************************************/
void SysTick_Handler (void)
{
  /* display LED 7 segment*/
  if(!LEDScanningTime)
  {
    /* refresh display */
    Seg7Disp_DisplayRefresh();
    /* reload period refresh */
    LEDScanningTime = LED_7SEG_REFRESH_PERIOD;
  }
  else
  {
    /* decrement timming */
    LEDScanningTime--;
  }
  
}
/********************** End Of File *************************/
/* VietComp Electronics Copyright  2013                     */
/************************************************************/
